package com.ds.api.utils;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

/**
 * 
 * @className: StringUtil
 * @description: 字符串处理集合类 主要功能：判断是否为null或者空,字符串是否在数组中,截取，字符在字符串中出现的次数等方法
 * @author yangzhiwei
 */
public class StringUtil {

    /**
     * 
     * @description: 截取指定字节长度的字符串
     * @param s 原来的字符
     * @param m 字节数
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String substring(String s, int m) {
        if (isBlank(s)) {
            return "";
        }
        long l = 0;
        String r = s;
        for (int i = 0; i < s.length() && i < m; i++) {
            int c = s.charAt(i);
            if (c > 127) {
                l = l + 2;
            }
            else {
                l = l + 1;
            }
            if (l >= m) {
                r = s.substring(0, i + 1);
                break;
            }
        }

        return r;
    }

    /**
     * 
     * @description: 截取英文字符串方法，超出部分用...表示，单词不截断
     * 
     * @param s 字符串
     * @param len 长度
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String substring4e(String s, int len) {
        if (s == null) {
            return "";
        }
        if (s.getBytes().length <= len) {
            return s;
        }
        while (!" ".equals(s.substring(len, len + 1)) && len > 0) {
            len--;
        }
        return substring(s, len) + "...";
    }

    /**
     * 
     * @description: TODO
     * @param s
     * @param len
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String substringSimple(String s, int len) {
        if (s.length() > len) {
            s = s.substring(0, len);
        }
        return s;
    }

    /**
     * 
     * @description: 亚洲语系(中文，日文，朝鲜语)截取字符串
     * @param s
     * @param len
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String multiSubstring(String s, int len) {
        if (s == null) {
            return "";
        }
        try {
            if (s.getBytes("Unicode").length <= len) {
                return s;
            }
        }
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return multiSubstring2(s, len) + "...";
    }

    /**
     * 
     * @description: TODO
     * @param s
     * @param length
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String multiSubstring2(String s, int length) {
        String s1 = s;
        try {
            byte[] bytes = s.getBytes("Unicode");
            int n = 0; // 表示当前的字节数
            int i = 2; // 要截取的字节数，从第3个字节开始

            for (; i < bytes.length && n < length; i++) {
                // 奇数位置，如3、5、7等，为UCS2编码中两个字节的第二个字节
                if (i % 2 == 1) {
                    n++; // 在UCS2第二个字节时n加1
                }
                else {
                    // 当UCS2编码的第一个字节不等于0时，该UCS2字符为汉字，一个汉字算两个字节
                    if (bytes[i] != 0) {
                        n++;
                    }
                }
            }

            // 如果i为奇数时，处理成偶数
            if (i % 2 == 1) {
                // 该UCS2字符是汉字时，去掉这个截一半的汉字
                if (bytes[i - 1] != 0) {
                    i = i - 1;
                }
                // 该UCS2字符是字母或数字，则保留该字符
                else {
                    i = i + 1;
                }
            }

            s1 = new String(bytes, 0, i, "Unicode");
        }
        catch (UnsupportedEncodingException u) {
            u.printStackTrace();
        }
        return s1;
    }

    /**
     * 
     * @description: 去除字符串空格
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String trim(String s) {
        if (s == null) {
            return "";
        }

        s = s.replaceAll("　", " ");
        s = s.replaceAll("\\s+", " ");

        return s.trim();
    }

    /**
     * 
     * @description: 以\s+格式截取字符串返回list
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static List<String> split(String s) {
        List<String> list = new ArrayList<String>();

        s = trim(s);
        if (s == null) {
            return list;
        }
        String[] rs = s.split("\\s+");

        for (int i = 0; i < rs.length; i++) {
            if (rs[i].trim().length() > 0) {
                list.add(rs[i]);
            }
        }

        return list;
    }

    /**
     * 
     * @description: 截取字符串返回string数组
     * @param s
     * @param delim
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String[] split2Array(String s, String delim) {
        List<String> list = split(s, delim);
        return (String[]) list.toArray(new String[0]);
    }

    /**
     * 
     * @description: 截取字符串
     * @param s 字符串
     * @param delim 截取方式
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static List<String> split(String s, String delim) {
        List<String> list = new ArrayList<String>();

        s = trim(s);
        if (s == null) {
            return list;
        }
        String[] rs = s.split(delim);

        for (int i = 0; i < rs.length; i++) {
            if (rs[i].trim().length() > 0) {
                list.add(rs[i]);
            }
        }

        return list;
    }

    /**
     * 
     * @description: 字符在字符串中出现的次数
     * @param string
     * @param a
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static int occurTimes(String string, String a) {
        int pos = -2;
        int n = 0;

        while (pos != -1) {
            if (pos == -2) {
                pos = -1;
            }
            pos = string.indexOf(a, pos + 1);
            if (pos != -1) {
                n++;
            }
        }
        return n;
    }

    /**
     * 
     * @description: 是否为空 null 或 ""
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static boolean nullOrSpace(String s) {
        if (s == null) {
            return true;
        }
        if (s.trim().length() == 0) {
            return true;
        }
        return false;
    }

    /**
     * 
     * @description: 是否为空
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static boolean isNull(String s) {
        return isBlank(s);
    }

    /**
     * 
     * @description: 返回字符串如果为null 则返回""
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String nullValue(String s) {
        return s == null ? "" : s.trim();
    }

    /**
     * 
     * @description: 返回字符串 如果为null 返回defaultValue
     * @param s
     * @param defaultValue 默认值
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String nullValue(String s, String defaultValue) {
        return s == null ? defaultValue : s;
    }

    /**
     * 
     * @description: TODO
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String nullValue(Object s) {
        return s == null ? "" : s.toString();
    }

    /**
     * 
     * @description: TODO
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String LongValue(Long s) {
        return s == null || s.intValue() <= 0 ? "" : s.toString();
    }

    /**
     * 
     * @description: TODO
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String LongValueZero(Long s) {
        return s == null || s.intValue() <= 0 ? "0" : s.toString();
    }

    /**
     * 
     * @description: TODO
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String LongValueOne(Long s) {
        return s == null || s.intValue() <= 0 ? "1" : s.toString();
    }

    /**
     * 
     * @description: TODO
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String nullValue(long s) {
        return s < 0 ? "" : String.valueOf(s);
    }

    /**
     * 
     * @description: TODO
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String nullValue(int s) {
        return s < 0 ? "" : "" + s;
    }

    /**
     * 
     * @description: 是否selected
     * @param arg
     * @param selectedValue
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String isSelected(String arg, String selectedValue) {
        return (arg != null && arg.equals(selectedValue)) ? "selected" : "";
    }

    /**
     * 
     * @description: 是否checked
     * @param arg
     * @param checkedValue
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String isChecked(String arg, String checkedValue) {
        return (arg != null && arg.equals(checkedValue)) ? "checked" : "";
    }

    /**
     * 
     * @description: 返回字符串如为null返回空
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String noNull(String s) {
        return replaceTNR(s);
    }

    /**
     * 
     * @description: TODO
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String noNull2CSVString(String s) {
        return s == null ? "\"\"" : "\"" + replaceTNR(s) + "\"";
    }

    /**
     * 
     * @description: TODO
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String noNull2CSVNumber(String s) {
        return s == null ? "\"\"" : "\"	" + replaceTNR(s) + "\"";
    }

    /**
     * 
     * @description: 转化为json适合的格式，如去掉空格，将双引号转化为转义格式
     * @param str
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String replaceToJsonType(String str) {
        return replaceTNR(str).replace("'", "\\'").replace("\"", "\\\"");
    }

    /**
     * 
     * @description: 去掉\n \t \r
     * @param str
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String replaceTNR(String str) {

        return str == null ? "" : str.replace("\t", " ").replace("\n", "").replace("\r", "");

    }

    /**
     * 
     * @description: 判断字符串是否为空
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static boolean isBlank(String s) {
        return s == null || s.trim().length() == 0;
    }

    /**
     * 
     * @description: TODO
     * @param object
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static boolean isNullObject(Object object) {
        return object == null;
    }

    /**
     * 
     * @description: 首字母大写
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String upperCaseFirst(String s) {
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }

    /**
     * 
     * @description: 字符串是否在字符串数组中 忽略大小写
     * @param url
     * @param allUrl
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static boolean in(String url, String[] allUrl) {
        for (int i = 0; i < allUrl.length; i++) {
            if (allUrl[i].equalsIgnoreCase(url)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 
     * @description: 字符串是否在字符串数组中 不忽略大小写
     * @param url
     * @param allUrl
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static boolean inWithCase(String url, String[] allUrl) {
        for (int i = 0; i < allUrl.length; i++) {
            if (allUrl[i].equals(url)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 
     * @description: 返回字符
     * @param n
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String getChar(int n) {
        return String.valueOf((char) n);
    }

    /**
     * 
     * @description: 返回字符
     * @param n 第几个
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String getCol(int n) {
        return String.valueOf((char) (n + 65));
    }

    /**
     * 
     * @description: 字符串中是否含有中文
     * @param s
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static boolean includeChinese(String s) {
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c > 100) {
                return true;
            }
        }
        return false;
    }

    /**
     * 
     * @description: 格式化sql
     * @param sql
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String escapeSql(String sql) {
        if (sql == null) {
            return null;
        }
        // TODO 非常重要，需要进一步丰富
        sql = sql.replaceAll("'", "''");
        sql = sql.replaceAll("_", "\\_");
        sql = sql.replaceAll("%", "\\%");
        sql = sql.replaceAll("\\(", "\\\\(");
        sql = sql.replaceAll("\\)", "\\\\)");
        return sql;
    }

    /**
     * 
     * @description: 格式化字符串并在前台加上空格
     * @param text
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String firstIndent(String text) {
        text = text.trim();
        text = text.replaceAll("&nbsp;", "");
        text = text.replaceAll("　", "");
        text = text.replaceAll("　", "");
        text = text.replaceAll("\\s+", "");
        return "&nbsp;&nbsp;&nbsp;&nbsp;" + text;
    }

    /**
     * 
     * @description: TODO
     * @param password
     * @param intensity
     * @param pwdLength
     * @return 密码强度 1 为低等强度 2为中等强度 3为高等强度
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static int validPassword(String password, String intensity, int pwdLength) {
        String[][] charGroup = {
                { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
                        "u", "v", "w", "x", "y", "z" },
                { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
                        "U", "V", "W", "X", "Y", "Z" }, { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" } };
        int level = 0;
        boolean[] flagGroup = { false, false, false };
        for (int i = 0; i < charGroup.length; i++) {
            String[] charSmallGroup = charGroup[i];

            for (int j = 0; j < password.length(); j++) {
                if (flagGroup[i]) {
                    continue;
                }

                String str = password.substring(j, j + 1);
                if (inWithCase(str, charSmallGroup)) {
                    level++;
                    flagGroup[i] = true;
                }
            }
        }

        return level;
    }

    /**
     * 
     * @description: 左边补零以满足长度要求
     * @param arg
     * @param resultLength 最终长度
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String addZeroLeft(String arg, int resultLength) {
        if (arg == null) {
            return "";
        }
        String result = arg;
        if (result.length() < resultLength) {
            for (int i = result.length(); i < resultLength; i++) {
                result = "0" + result;
                if (result.length() == resultLength) {
                    break;
                }
            }
        }
        return result;
    }

    /**
     * 
     * @description: 获取相同字符的个数；
     * @param str1
     * @param str2
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static int getSameCharCount(String str1, String str2) {
        return StringUtils.countMatches(str1, str2);
    }

    /**
     * 
     * @description: TODO
     * @param big
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String formatDecimal(BigDecimal big) {
        String pattern = "###,##0.00";
        DecimalFormat df = new DecimalFormat(pattern);
        return df.format(big);

    }

    /**
     * 
     * @description: TODO
     * @param str
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String encode(String str) {

        try {

            str = URLEncoder.encode(str, "utf-8");

        }
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return str;
    }

    /**
     * 
     * @description: TODO
     * @param str
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String decode(String str) {

        if (str == null || "".equals(str))
            return "";

        try {

            str = URLDecoder.decode(str, "utf-8");

        }
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return str;
    }

    /**
     * 
     * @description: sql语句正则表达式转义字符转换
     * @param sql
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String regexpSqlReplace(String sql) {

        return sql.replace("[", "\\[").replace("]", "\\]").replace("(", "\\(").replace(")", "\\)").replace("*", "\\*")
                .replace("+", "\\+").replace("?", "\\?").replace(".", "\\.").replace("^", "\\^");
    }

    /**
     * 
     * @description: 重复生成N次组成新的字符串。
     * @param src
     * @param num
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String repeat(String src, Long num) {

        StringBuffer s = new StringBuffer();
        for (int i = 0; i < num; i++) {
            s.append(src);
        }
        return s.toString();

    }

    /**
     * 
     * @description: TODO
     * @param str
     * @param temp
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static int containNum(String str, String temp) {
        if (str == null || temp == null || "".equals(str) || "".equals(temp)) {
            return 0;
        }
        int i = 0;
        int count = 0;
        while (true) {
            i = str.indexOf(temp);
            if (i > -1) {

                count++;
                str = str.substring(i + temp.length(), str.length());

            }
            else {
                break;
            }
        }
        return count;
    }

    /**
     * 
     * @description: TODO
     * @param array
     * @param separator
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String concatArray(String[] array, String separator) {

        if (array == null || array.length == 0)
            return "";

        if (separator == null)
            separator = "";

        StringBuffer buffer = new StringBuffer();

        for (String str : array) {
            buffer.append(str).append(separator);
        }

        String temp = buffer.toString();

        if (temp.endsWith(separator)) {

            temp = temp.substring(0, temp.length() - separator.length());
        }
        return temp;
    };

    /**
     * 
     * @description: TODO
     * @param fileName
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String getExtention(String fileName) {
        int pos = fileName.lastIndexOf(".");
        return fileName.substring(pos);
    }

    /**
     * 
     * @description: 替换字符串
     * @param str
     * @param newChar
     * @param oldChar
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String replace(String str, String newChar, String... oldChar) {
        for (String oc : oldChar) {
            str = str.replace(oc, newChar);
        }
        return str;
    }

    /**
     * 
     * @description: 反转日期字符串 如（yyyy-MM-dd 反转成 dd/MM/yyyy）
     * @param date
     * @param oldConnector
     * @param newConnector
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String reverseDate(String date, String oldConnector, String newConnector) {
        String newDate = "";
        if (StringUtils.isNotEmpty(date)) {
            String[] dateArray = date.split(oldConnector);
            for (int i = dateArray.length - 1; i >= 0; i--) {
                if (i > 0 && i <= dateArray.length - 1) {
                    newDate += dateArray[i] + newConnector;
                }
                else {
                    newDate += dateArray[i];
                }
            }
        }
        return newDate;
    }

    /**
     * 
     * @description: 判断字符串是否不为null且不为""
     * @param str
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    /**
     * 
     * @description: 判断字符串是否为null或为""
     * @param str
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static boolean isEmpty(String str) {
        return str == null || "".equals(str);
    }

    /**
     * 
     * @description: TODO
     * @param value 要处理的值
     * @param oldChar 要被替换的值
     * @param newChar 替换的值
     * @param size 替换的次数
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String replace(String value, String oldChar, String newChar, int size) {
        int index = 0;
        int count = 0;
        StringBuffer sb = new StringBuffer(value);
        while ((index = sb.indexOf(oldChar)) != -1 && (count < size)) {
            sb.replace(index, index + oldChar.length(), newChar);
            count++;
        }
        return sb.toString();
    }

    /**
     * 
     * @description: TODO
     * @param obj
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String toString(Object obj) {
        if (obj != null) {
            return obj.toString();
        }
        return null;
    }

    /**
     * 
     * @description: 字符串数组转为字符串
     * @param str
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String arrayToString(String[] str) {
        if (str == null) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < str.length; i++) {
            if (StringUtil.isEmpty(str[i])) {
                continue;
            }
            if (sb.length() > 0) {
                sb.append(",");
            }
            sb.append(str[i]);

        }
        return sb.toString();
    }

    /**
     * 
     * @description: 组成立刻模糊查询,0-两边加上%，-1左边，1-右边
     * @param type
     * @param str
     * @return
     * @author yangzhiwei
     * @date 2017-5-15
     */
    public static String likeString(int type, String str) {
        if (type == -1) {
            return MessageFormat.format("%{0}", str);
        }
        if (type == 1) {
            return MessageFormat.format("{0}%", str);
        }

        return MessageFormat.format("%{0}%", str);

    }
    
    /**
     * 补齐不足长度
     * @param length 长度
     * @param number 数字
     * @return
     */
    public static String lpad(int length, String number) {
        int leng = number.length();

        for (int i = 0; i < 6 - leng; i++) {
            number = "0" + number;
        }
        return number;
    }
}
